#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <cstdio>
#include "LockGuard.hpp"
#define NUM 4
using namespace std;

int tickets = 1000; // 总共票数

/*
class threadData
{
public:
    threadData(int number,pthread_mutex_t* mutex)
    {
        _threadName = "thread-" + to_string(number);
        _lock=mutex;
    }

public:
    string _threadName;
    pthread_t _tid;
    pthread_mutex_t* _lock;
};

void* getTicket(void* args){
    threadData* td=static_cast<threadData*> (args);
    const char* name=td->_threadName.c_str();
    while(true){
        pthread_mutex_lock(td->_lock);
        if(tickets>0){
            usleep(1000);
            --tickets;
            printf("%s抢了1张票，还剩%d张票\n",name,tickets);
            pthread_mutex_unlock(td->_lock);
        }else{
            pthread_mutex_unlock(td->_lock);
            break;
        }
        usleep(10);
    }

    printf("票已售空!\n");
    return nullptr;
}

int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex,nullptr);
    vector<threadData*> threadDatas;
    for(int i=1;i<=NUM;++i){
        threadData* td=new threadData(i,&mutex);
        threadDatas.push_back(td);
        pthread_create(&(td->_tid),nullptr,getTicket,threadDatas[i-1]);
    }

    for(auto thread:threadDatas){
        pthread_join(thread->_tid,nullptr);
    }

    for(auto td:threadDatas){
        delete td;
    }

    pthread_mutex_destroy(&mutex);
    return 0;
}
*/

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
class threadData
{
public:
    threadData(int number, pthread_mutex_t *mutex)
    {
        _threadName = "thread-" + to_string(number);
        _lock = mutex;
    }

public:
    string _threadName;
    pthread_t _tid;
    pthread_mutex_t *_lock;
};

void *getTicket(void *args)
{
    threadData *td = static_cast<threadData *>(args);
    const char *name = td->_threadName.c_str();
    while (true)
    {
        {
            LockGuard lg(&mutex); // 临时的LockGuard对象  RAII风格的锁
            if (tickets > 0)
            {
                usleep(1000);
                --tickets;
                printf("%s抢了1张票，还剩%d张票\n", name, tickets);
            }
            else
            {

                break;
            }
        }
        usleep(10);
    }

    printf("票已售空!\n");
    return nullptr;
}

int main()
{
    vector<threadData *> threadDatas;
    for (int i = 1; i <= NUM; ++i)
    {
        threadData *td = new threadData(i, &mutex);
        threadDatas.push_back(td);
        pthread_create(&(td->_tid), nullptr, getTicket, threadDatas[i - 1]);
    }

    for (auto thread : threadDatas)
    {
        pthread_join(thread->_tid, nullptr);
    }

    for (auto td : threadDatas)
    {
        delete td;
    }

    return 0;
}